//======================================================================
//    COPYRIGHT(C) Innobeam
//    ALL RIGHTS RESERVED
//======================================================================
//Filename    : lan9252_interface.v
//Created On  : 20170802
//Author      : 
//Description :This module write and read 16bit data to lan9252;
// through HBI bus.(require 10 iClk cycles)
//Include     : ModuleName1 ver ……
//Modification: xxx by aaa on date
//=======================================================================
module lan9252_interface_back (//input
					iClk   		,//50Mhz(LAN9252 RD and WR need 2 iClks)
					iRstN           ,
					ivData			,//32bit input
					ivAddr			,//16bit input address
					iWrEn			,//write iClk
					iRdEn           ,
					ovData  		,//32bit output data from lan9252
					oLan9252AleL 	,//output,LAN9252 ALELO
					oLan9252AleH 	,//output,LAN9252 ALEHI
					oLan9252Cs		,//output,LAN9252 cs
					oLan9252Rd 		,//output,LAN9252 rd
					oLan9252Wr 		,//output,LAN9252 wr
					iovLan9252Ad 	,//16bit inout,LAN9252 ad
					oDone           
					);
//==========================================
//    parameter
//==========================================
parameter	DATA_W = 16;

//==========================================
//    port
//==========================================
input 						iClk,iRstN;
input 	[2*DATA_W-1:0]		ivData;
input 	[DATA_W-1:0]		ivAddr;
input 						iWrEn,iRdEn;
output 	[2*DATA_W-1:0]		ovData;
output						oLan9252AleL;
output						oLan9252AleH;
output						oLan9252Cs;
output						oLan9252Rd;
output						oLan9252Wr;
inout 	[DATA_W-1:0] 		iovLan9252Ad;
output						oDone;

//==========================================
//    signal
//==========================================
reg		[DATA_W-1:0] 		ioLan9252Ad_reg;
reg 						oLan9252AleL,oLan9252Cs,oLan9252Rd,oLan9252Wr;
reg 						oDone;
reg 	[3:0]				rvState;
reg 	[2:0]				rcnt;
reg 	[15:0]				reg9252[1:0];
reg 	[DATA_W-1:0]  		rvAddr;
reg 	[2*DATA_W-1:0] 		rvData;

assign ovData = {reg9252[1],reg9252[0]};
assign oLan9252AleH = 1'b0;
assign iovLan9252Ad = oLan9252Rd?16'hz:ioLan9252Ad_reg;



always@(posedge iClk or negedge iRstN)
if(!iRstN)begin
	rvState <= 4'd0;
	rcnt <= 3'd0;
	oLan9252Rd <= 1'b0;
	oLan9252Wr <= 1'b0;
	oLan9252AleL <= 1'b0;
	oLan9252Cs <= 1'b0;
	ioLan9252Ad_reg <= 16'd0;
	oDone <= 1'b0;
	reg9252[0] <= 1'b0;
	reg9252[1] <= 0;
	end
else begin
	if(rvState == 4'd0) begin
		if(iWrEn == 1'b1) begin
			rcnt <= 3'd0;
			rvAddr <= ivAddr;
			rvData <= ivData;
			oDone <= 1'b0;
			rvState <= 4'd9; //lan9252 write
			end//if
		else if(iRdEn ==1'b1) begin
			rcnt <= 3'd0;
			rvAddr <= ivAddr;
//			rvData <= ivData;
			oDone <= 1'b0;
			rvState <= 4'd2; //lan9252 read
			end
		else begin
			oDone <= 1'b0;
			end//else
		end//if
//read lan9252 process
	else if(rvState == 4'd2) begin
		ioLan9252Ad_reg <= rvAddr;
		oLan9252AleL <= 1'b1;
		oLan9252Cs <= 1'b1;
		rvState <= 4'd3;
		end
	else if(rvState == 4'd3) begin
		oLan9252AleL <= 1'b0;
		rvState <= 4'd4;
		end
	else if(rvState == 4'd4) begin
		oLan9252Rd <= 1'b1;
		rvState <= 4'd5;
		end
	else if(rvState == 4'd5) begin
		rvState <= 4'd6;  //wait for 1 iClk,RD data 30ns Valid
		end
	else if(rvState == 4'd6) begin
		rvState <= 4'd7;  //wait for 2 iClk,RD data 30ns Valid
		end
	else if(rvState == 4'd7) begin
		oLan9252Rd <= 1'b0;
		oLan9252Cs <= 1'b0;
		if(rcnt == 3'd0) begin
			reg9252[0] <= iovLan9252Ad;
			rvAddr <= rvAddr + 1'b1;
			rcnt <= rcnt + 1'b1;
			rvState <= 4'd2;
			end
		else begin
			reg9252[1] <= iovLan9252Ad;
			rvState <= 4'd0;
			oDone <= 1'b1;
			end
		end
//write lan9252 process
	else if(rvState == 4'd9) begin
		ioLan9252Ad_reg <= rvAddr;
		oLan9252AleL <= 1'b1;
		oLan9252Cs <= 1'b1;
		rvState <= 4'd10;
		end
	else if(rvState == 4'd10) begin
		oLan9252AleL <= 1'b0;
		rvState <= 4'd11;
		end
	else if(rvState == 4'd11) begin
		oLan9252Wr <= 1'b1;
		if(rcnt == 3'd0) begin
			ioLan9252Ad_reg <= rvData[15:0];
			end
		else begin
			ioLan9252Ad_reg <= rvData[31:16];
			end
		rvState <= 4'd12;
		end
	else if(rvState == 4'd12) begin
		rvState <= 4'd13;
		end
	else if(rvState == 4'd13) begin
		oLan9252Wr <= 1'b0;
		oLan9252Cs <= 1'b0;
		if(rcnt == 3'd0) begin
			rvAddr <= rvAddr + 1'b1;
			rcnt <= rcnt + 1'b1;
			rvState <= 4'd9;
			end
		else begin
			rvState <= 4'd0;
			oDone <= 1'b1;
			end
		end
	end

endmodule
					
					
					
					
					